"""
Hot key support
Author: Roee Shlomo
"""
import wx

keyMap = {}

def gen_keymap():
    keys = ("BACK", "TAB", "RETURN", "ESCAPE", "SPACE", "DELETE", "START",
        "LBUTTON", "RBUTTON", "CANCEL", "MBUTTON", "CLEAR", "PAUSE",
        "CAPITAL", "PRIOR", "NEXT", "END", "HOME", "LEFT", "UP", "RIGHT",
        "DOWN", "SELECT", "PRINT", "EXECUTE", "SNAPSHOT", "INSERT", "HELP",
        "NUMPAD0", "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD4", "NUMPAD5",
        "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9", "MULTIPLY", "ADD",
        "SEPARATOR", "SUBTRACT", "DECIMAL", "DIVIDE", "F1", "F2", "F3", "F4",
        "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14",
        "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24",
        "NUMLOCK", "SCROLL", "PAGEUP", "PAGEDOWN", "NUMPAD_SPACE",
        "NUMPAD_TAB", "NUMPAD_ENTER", "NUMPAD_F1", "NUMPAD_F2", "NUMPAD_F3",
        "NUMPAD_F4", "NUMPAD_HOME", "NUMPAD_LEFT", "NUMPAD_UP",
        "NUMPAD_RIGHT", "NUMPAD_DOWN", "NUMPAD_PRIOR", "NUMPAD_PAGEUP",
        "NUMPAD_NEXT", "NUMPAD_PAGEDOWN", "NUMPAD_END", "NUMPAD_BEGIN",
        "NUMPAD_INSERT", "NUMPAD_DELETE", "NUMPAD_EQUAL", "NUMPAD_MULTIPLY",
        "NUMPAD_ADD", "NUMPAD_SEPARATOR", "NUMPAD_SUBTRACT", "NUMPAD_DECIMAL",
        "NUMPAD_DIVIDE")
    
    for i in keys:
        keyMap[getattr(wx, "WXK_"+i)] = i

def GetKeyPress(evt):
    wxkeycode = evt.GetKeyCode()
    keyname = keyMap.get(wxkeycode, None)
    modifiers = ""
    modifiers_code = None
    
    for mod, ch, hkmod in ((evt.ControlDown(), 'Ctrl+',  wx.MOD_CONTROL ),
                           (evt.AltDown(),     'Alt+',   wx.MOD_ALT),
                           (evt.ShiftDown(),   'Shift+', wx.MOD_SHIFT)):
        if mod:
            modifiers += ch
            if modifiers_code is None:
                modifiers_code = hkmod
            else:
                modifiers_code = modifiers_code | hkmod
            
    if modifiers == "":
        return "", None, None, None

    if keyname is None:
        if 27 < wxkeycode < 256:
            keyname = chr(wxkeycode)
        else:
            keyname = ""
            
    keycode = evt.GetRawKeyCode()
    if keycode in [16, 17, 18]:
        keycode = None
    
    return modifiers + keyname, modifiers_code, keycode, wxkeycode

class HotKeyTextCtrl(wx.TextCtrl):
    def __init__(self, parent, size=wx.DefaultSize):
        wx.TextCtrl.__init__(self, parent, -1, size=size, style=wx.WANTS_CHARS|wx.TE_RICH2)
        gen_keymap()
        self._reset()
        
        self.Bind(wx.EVT_KEY_DOWN, self.KeyPressed)
        self.Bind(wx.EVT_SET_FOCUS, self.onFocus)
        self.Bind(wx.EVT_KILL_FOCUS, self.onKillFocus)
        

    def _reset(self):
        self.keys = None
        self.wxkeys = None
        self.modifiers = None
        self.SetValue('')
        
    def onFocus(self, event):
        if not utility.frame.UnregisterHotKey(utility.hotkey["ID"]):
            utility.frame.Bind(wx.EVT_HOTKEY, self.Skip, id = utility.hotkey["ID"])

    def onKillFocus(self, event):
        if utility.config.Read('hotkey', "boolean"):
            utility.frame.Bind(wx.EVT_HOTKEY, utility.frame.HotKeyDown, id = utility.hotkey["ID"])
        
    def Update(self):
        for item in [self.keys, self.wxkeys, self.modifiers]:
            if item is None or item == 0:
                self._reset()
                return
            
        keyname = keyMap.get(self.wxkeys, None)
        if not keyname:
            if 27 < self.wxkeys < 256:
                keyname = chr(self.wxkeys)
            else:
                #keyname = ""
                return
            
        if self.modifiers == 1: #ALT
            modifiers = 'Alt+'
        elif self.modifiers == 2: #CTRL
            modifiers = 'Ctrl+'            
        elif self.modifiers == 4: #SHIFT
            modifiers = 'Shift+'
        elif self.modifiers == 3: #CTRL+ALT
            modifiers = 'Ctrl+Alt+'
        elif self.modifiers == 5: #SHIFT+ALT
            modifiers = 'Alt+Shift+'
        elif self.modifiers == 6: #CTRL+SHIFT
            modifiers = 'Ctrl+Shift+'
        elif self.modifiers == 7: #CTRL+SHIFT+ALT
            modifiers = 'Ctrl+Alt+Shift+'
        else:
            #modifiers = ''
            return
        
        self.SetValue(modifiers + keyname)
        
    def KeyPressed(self, evt):        
        key, modifiers, keycode, wxkeycode = GetKeyPress(evt)
        if key == 'ESCAPE':
            self._reset()
        else:
            self.SetValue(key)
        self.modifiers = modifiers
        self.keys = keycode
        self.wxkeys = wxkeycode

    def Skip(self, evt):
        Read = utility.config.Read
   
        self.modifiers = utility.hotkey["current"]["modifiers"]
        self.keys = utility.hotkey["current"]["keys"]
        self.wxkeys = utility.hotkey["current"]["wxkeycode"]     
        self.Update()
